package model.management;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import model.entity.container.ProductGroup;

import common.Result;

/**
 * Track the instance of the list of product group
 * 
 * @author Ian Ryu
 * 
 *         {@invariant productGroups.size() >= 0}
 * 
 */

public enum ProductGroupManager implements Serializable
{
  INSTANCE;

  private List<ProductGroup> productGroups = new ArrayList<ProductGroup>();

  /**
   * Validates whether the given product group can be added to product group.
   * 
   * @param productgroup
   *          The product group to validate.
   * 
   * @return a result, whose status indicates whether the given product group has valid attributes.
   * 
   *         {@pre productgroup != null}
   * 
   */
  public static Result validateAddProductGroup(ProductGroup productgroup)
  {
    // TODO: implement
    // NOTE TO IMPLEMENTER: as per StorageUnit.validateAddProductGroup(ProductGroup), this method
    // strictly checks for valid attribues,
    // not whether it can be added to a specific container. That is handled by the container class.
    return new Result(true);
  }

  /**
   * Validates whether the given product group can be added to this product container. If so, the
   * product group is added to this container.
   * 
   * @param productgroup
   *          The product group to be added to this container.
   * 
   * @return a result, indicating whether this operation was successful or not.
   * 
   *         {@pre productgroup != null} {@pre productGroups.size() = (old)productGroups.size() +
   *         1}
   */
  public static Result addProductGroup(ProductGroup productgroup)
  {
    Result canAdd = validateAddProductGroup(productgroup);
    if (!canAdd.getStatus())
    {
      return canAdd;
    }
    
    INSTANCE.productGroups.add(productgroup);
    return new Result(true);
  }

  /**
   * Validates whether the given product group can be removed from product group.
   * 
   * @param productGroup
   *          The product group to validate.
   * 
   * @return a result, whose status indicates whether the given product group can be removed from
   *         this container.
   * 
   *         {@pre productgroup != null} {@post retval != null}
   * 
   */
  public static Result validateRemoveProductGroup(ProductGroup productGroup)
  {
    if (productGroup == null)
    {
      return new Result(false);
    }
    else if (!INSTANCE.productGroups.contains(productGroup))
    {
      return new Result(false);
    }
    
    return new Result(true);
  }

  /**
   * Validates whether the given product group can be removed from this product group container. If
   * so, the product group is removed from this container.
   * 
   * @param productgroup
   *          The product group to be removed from this container.
   * 
   * @return a result, indicating whether this operation was successful or not.
   * 
   *         {@pre productgroup != null} {@pre productGroup.size() = (old)productGroups.size() - 1}
   * 
   */
  public static Result removeProductGroup(ProductGroup productgroup)
  {
    Result canRemove = validateRemoveProductGroup(productgroup);
    if (!canRemove.getStatus())
    {
      return canRemove;
    }
    
    INSTANCE.productGroups.remove(productgroup);
    return new Result(true);
  }

  /**
   * Validates whether the given product group can be updated.
   * 
   * @param productgroup
   *          The product group to validate.
   * 
   * @return a result, whose status indicates whether the given product group can be updated.
   * 
   *         {@pre productgroup != null}
   * 
   */
  public static Result validateUpdateProductGroup(ProductGroup productgroup)
  {
    return new Result(true);
  }

  /**
   * Validates whether the given product group can be updated this product container. If so, the
   * product group is updated.
   * 
   * @param productgroup
   *          The product group to be updated this container.
   * 
   * @return a result, indicating whether this operation was successful or not.
   * 
   *         {@pre productgroup != null} {@post productGroups.size == (old)productGroups.size()}
   * 
   */
  public static Result updateProductGroup(ProductGroup productgroup)
  {
    return null;
  }

  /**
   * @return An iterator of all <code>Product</code>s in the system.
   */
  public Iterator<ProductGroup> getIterator()
  {
    return null;
  }

  /**
   * Clears all ProductGroup data.
   */
  public static void clear()
  {
    INSTANCE.productGroups.clear();
  }
}
